package datacommit

import (
	"encoding/base64"
	"errors"
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"strings"
	"time"

	"github.com/rs/zerolog/log"
)

type Developer struct {
	NameRep string `json:"name"`
	NameGit string
	ExtId   string `json:"extId"`
	Email   string
}

type DataProccessor struct {
	Data string `json:"base64data"`
	Type string `json:"type"`
	Name string `json:"name"`
}

type Commit struct {
	Dev        Developer      `json:"author"`
	TextCommit string         `json:"textCommit"`
	DP         DataProccessor `json:"DataProccessor"`
	Source     string         `json:"source"`
	BranchName string         `json:"branchname"`
}

func (c *Commit) CreateCommit(wd string) error {

	err := c.LoadDevelopers(wd)
	if err != nil {
		return err
	}

	for _, cCMD := range cmdPart1(wd, c.BranchName) {
		err = system_exec(cCMD, wd)
		if err != nil {
			return err
		}
	}

	dataFile := c.DP.Data

	c.DP.Name = strings.Replace(c.DP.Name, "/", "_", -1)
	c.DP.Name = strings.Replace(c.DP.Name, "\\", "_", 0)
	c.DP.Name = strings.Replace(c.DP.Name, "-", "_", 0)

	pathFile := wd + "\\DataProcessorsExt\\Обработка\\" + c.DP.Name + ".epf"

	if strings.ToLower(c.DP.Type) != "обработка" {
		pathFile = wd + "\\DataProcessorsExt\\Отчет\\" + c.DP.Name + ".erf"
	}

	file, err := os.Create(pathFile)
	if err != nil {
		return err
	}

	log.Info().Msg(pathFile)
	// defer file.Close()

	sDec, err := base64.StdEncoding.DecodeString(dataFile)
	if err != nil {
		return err
	}

	_, err = file.Write(sDec)
	if err != nil {
		return err
	}
	file.Close()
	//-c diff.mnemonicprefix=false -c core.quotepath=false --no-optional-locks commit -v -q
	for _, cCMD := range cmdPart2(c) {
		if cCMD == "git commit" {
			cmdText := fmt.Sprintf("git -c core.quotepath=false --no-optional-locks commit --author=%s<%s> -v -q -m", c.Dev.NameGit, c.Dev.Email)
			log.Info().Msg("commit: " + cmdText + c.TextCommit)
			arg := strings.Split(cmdText, " ")
			arg = append(arg, c.TextCommit)
			cm := exec.Command(arg[0], arg[1:]...)
			cm.Dir = wd
			b, _ := cm.CombinedOutput()
			log.Info().Msg("commit object! : " + c.DP.Name)
			log.Info().Msg("Done commit! : " + string(b))
			// if err != nil || strings.Contains(txtErr, st) == false {
			// 	log.Error().Err(err).Msg("Error Commit: " + txtErr)
			// 	return errors.New(txtErr)
			// } else {
			// 	log.Info().Msg("Done commit! : ")
			// }
			time.Sleep(time.Second * 5)
			continue
		}
		err = system_exec(cCMD, wd)
		if err != nil {
			return err
		}
	}
	return err
}

func (c *Commit) LoadDevelopers(wd string) error {

	filename := wd + "/developers"
	data, err := ioutil.ReadFile(filename)
	if err != nil {
		return err
	}
	data = []byte(strings.Replace(string(data), "ufeff", "", 0))
	collect := strings.Split(string(data), "\r\n")
	for _, dev := range collect {
		cdev := strings.Split(dev, "=")

		if strings.ToLower(cdev[0]) == strings.ToLower(c.Dev.NameRep) {
			c.Dev.Email = cdev[1]
			c.Dev.NameGit = cdev[2]
			break
		}
	}
	if c.Dev.Email == "" {
		return errors.New("Not setting developer " + c.Dev.NameRep)
	} else {
		return nil
	}
}

func cmdPart1(wd string, branch string) []string {

	var cmds []string
	cmds = append(cmds, "cmd cd "+wd)
	cmds = append(cmds, "git reset --hard")
	cmds = append(cmds, "git checkout "+branch)
	cmds = append(cmds, "git pull origin")

	return cmds
}

func cmdPart2(c *Commit) []string {

	var cmds []string
	cmds = append(cmds, "git add -A")
	cmds = append(cmds, "git status")
	cmds = append(cmds, "git commit")
	cmds = append(cmds, "git status")
	cmds = append(cmds, "git push -u origin develop:develop")
	return cmds
}

func system_exec(str_cmd string, wd string) error {

	arg := strings.Split(str_cmd, " ")
	c := exec.Command(arg[0], arg[1:]...)

	c.Dir = wd
	b, err := c.CombinedOutput()
	if err != nil {
		log.
			Error().
			Err(err).
			Msg("Error: " + str_cmd)
		return err
	} else {
		log.
			Info().
			Msg("Done! " + str_cmd)
		log.
			Info().
			Msg("Подробно: " + string(b))

		return nil
	}

}
